package com.stone.framework.auth.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.stone.framework.core.cache.UserConstant;
import com.stone.framework.message.ReqMessage;
import com.stone.framework.message.ResMessage;
import com.stone.framework.message.user.LoginInfoReqBody;
import com.stone.framework.message.user.LoginInfoResBody;
import com.stone.framework.message.user.TokenInfoReqBody;
import com.stone.framework.message.user.TokenInfoResBody;

import feign.hystrix.FallbackFactory;

@FeignClient(name = "stone-user-service", fallbackFactory = UserClient.UserFallbackFactory.class)
public interface UserClient {

    Logger LOGGER = LoggerFactory.getLogger(UserClient.class);

    @RequestMapping(value = "/user/getLoginInfo", method = RequestMethod.POST)
    ResMessage<LoginInfoResBody> getLoginInfo(ReqMessage<LoginInfoReqBody> reqMessage);

    @RequestMapping(value = "/user/getTokenInfo", method = RequestMethod.POST)
    ResMessage<TokenInfoResBody> getTokenInfo(ReqMessage<TokenInfoReqBody> reqMessage);

    @Cacheable(value = UserConstant.LOGIN_INFO, key = "#username", unless = "#result == null")
    default LoginInfoResBody getLoginInfo(String username) {
        LoginInfoReqBody reqBody = new LoginInfoReqBody();
        reqBody.setUsername(username);
        ResMessage<LoginInfoResBody> resMessage = this.getLoginInfo(ReqMessage.build(reqBody));
        return resMessage.getBody();
    }

    @Cacheable(value = UserConstant.TOKEN_INFO, key = "#username", unless = "#result == null")
    default TokenInfoResBody getTokenInfo(String username) {
        TokenInfoReqBody reqBody = new TokenInfoReqBody();
        reqBody.setUsername(username);
        ResMessage<TokenInfoResBody> resMessage = this.getTokenInfo(ReqMessage.build(reqBody));
        return resMessage.getBody();
    }

    @Component
    public static class UserFallbackFactory implements FallbackFactory<UserClient> {

        @Override
        public UserClient create(Throwable cause) {
            return new UserClient() {

                @Override
                public ResMessage<LoginInfoResBody> getLoginInfo(ReqMessage<LoginInfoReqBody> reqMessage) {
                    LOGGER.error("getLoginInfo()调用异常", cause);
                    return ResMessage.success(null);
                }

                @Override
                public ResMessage<TokenInfoResBody> getTokenInfo(ReqMessage<TokenInfoReqBody> reqMessage) {
                    LOGGER.error("getTokenInfo()调用异常", cause);
                    return ResMessage.success(null);
                }

            };
        }

    }

}
